﻿#include "swi_typical_parameter.h"
#include "swi_parameter_check.h"
#include "out_batch_analysis.h"
#include "stability_analysis.h"

std::vector<Swi::TypicalGenerator> ReadTypicalSwi(std::string filename)
{
    std::vector<Swi::TypicalGenerator> typical_generator_list;
    Swi::TypicalParameter typical_parameter;
    typical_generator_list = typical_parameter.ReadTypicalSwi(filename);

    return typical_generator_list;
}

int TypicalGeneratorReplace(Swi::SwiFile swi_file, Swi::TypicalGenerator typical_generator, std::string replace_generator_name)
{
    Swi::TypicalParameter typical_parameter;
    typical_parameter.TypicalGeneratorReplace(swi_file, typical_generator, replace_generator_name);

    return 1;
}

int SwiParameterCheck(Swi::SwiFile swi_file, Dat::DatFile dat_file)
{
    Swi::ParameterCheck parameter_check;
    parameter_check.ParameterCheckByDat(swi_file, dat_file);

    return 1;
}

int SwiBatchCalculate(std::string swi_filename, const SwiBatchParameter& batch_parameter)
{
    // 调用开始前设置循环退出为false
    ToExecuteSwi::SetBreakCycle(false);

    // create temp file
    string tempDir = "./bpa_temp/swi_multi_calculate/";
    if (!JGG::filesystem::CDirectory::isdir(tempDir))
    {
        JGG::filesystem::CDirectory::mkdir(tempDir);
    }
    else
    {
        JGG::filesystem::CDirectory::rmdir(tempDir);
        JGG::filesystem::CDirectory::mkdir(tempDir);
    }

    // copy pfnt.exe and swnt.exe
    const string origpfnt = "./pfnt.exe";
    const string origswnt = "./swnt.exe";
    const string newpfnt = "./bpa_temp/swi_multi_calculate/pfnt.exe";
    const string newswnt = "./bpa_temp/swi_multi_calculate/swnt.exe";
    if (JGG::filesystem::CFile::exists(origpfnt) && JGG::filesystem::CFile::exists(origpfnt))
    {
        JGG::filesystem::CFile::copy(origpfnt, newpfnt);
        JGG::filesystem::CFile::copy(origswnt, newswnt);
    }
    else
    {
        // TODO: 输出日志
    }

    BPA::BPAFilesIO::Db2Dat inst;
    string outDat = "./bpa_temp/swi_multi_calculate/temp.dat";
    inst.DataBaseWriteToBpa(database, outDat.c_str(), DatCaseID);

    // call pfnt.exe
    std::string command = ".\\bpa_temp\\swi_multi_calculate\\pfnt.exe .\\bpa_temp\\swi_multi_calculate\\temp.dat";
    JGG::Process process(command);
    int exit_status = process.get_exit_status();

    BPA::BPAFilesIO::DatParse* datParser = new BPA::BPAFilesIO::DatParse();
    datParser->Parsing(outDat.c_str());
    datParser->TrimBpaDat1();
    datParser->TrimBpaDat2();
    datParser->GetZoneProvinceID(database);

    if (ToExecuteSwi::GetBreakCycle())
        return STS_SUCCEED;

    //故障卡的生成
    BPA::BPAFilesIO::GetDatFromDb *getDatFromDb = new BPA::BPAFilesIO::GetDatFromDb(
        datParser,
        database,
        DatCaseID);

    swical::LineFaultCreate(
        database,
        DatCaseID,
        getDatFromDb,
        datParser,
        batch_parameter.ZoneName,
        batch_parameter.VolMin,
        batch_parameter.VolMax);

    if (ToExecuteSwi::GetBreakCycle())
        return 1;

    //进行批量稳定计算
    ToExecuteSwi toExecuteSwi(database, DatCaseID, SwiCaseID);
    toExecuteSwi.MultiExeSwi(DatCaseID, SwiCaseID, batch_parameter);
    return 1;
}

// out文件解析全过程
int OutBatchAnalysis()
{

    std::vector <std::string> files =
        filesystem::CPath::has_extension("./bpa_temp/swi_multi_calculate/", "BSE", false);
    std::string BseName = files[0];

    int BseExist = 1;
    if (!filesystem::CFile::exists(BseName))
    {
        BseExist = 0;
    }

    //OUT文件类型
    const char OutFileType[10] = ".OUT";
    //SWI文件类型
    const char SWIFileType[10] = ".SWI";

    // out 文件统计
    int MaxSeq = 0;
    std::string dir = "./bpa_temp/swi_multi_calculate/";
    std::string swiFileNameTemp = "temp.swi";
    try
    {
        if (filesystem::CPath::is_directory(dir))
        {
            std::vector <std::string> files = filesystem::CPath::has_extension(dir, "OUT", false);
            MaxSeq = files.size();
        }
        else
        {
            // TODO: 输出日志
        }
    }
    catch (std::exception&)
    {
        throw JGG::OpenFileException();
    }

    std::string OutFilesPath;												//添加编号后的路径
    string NewSWIFileNamePath;												//添加编号后的路径
    char FileSeq[10];															//文件编号
    for (int i = 1; i < MaxSeq + 1; i++)
    {
        std::string swiFileNameNoExtended = swiFileNameTemp.substr(0, swiFileNameTemp.size() - 4);
        stringstream oss("");
        oss << dir << swiFileNameNoExtended << "_" << i << OutFileType;
        OutFilesPath = oss.str();

        ifstream OutFileOpen;
        try
        {
            OutFileOpen.open(OutFilesPath.c_str(), ios::in);
        }
        catch (std::exception&)
        {
            throw JGG::FileException();
        }

        ofstream LogOut("LogInfo.txt ", ios::app);

        if (!OutFileOpen)
        {
            // TODO: 输出日志，文件不存在
        }
        else
        {
            OutFileOpen.close();
            int Completeness1 = 0;
            try
            {
                Completeness1 = CompletenessCheck(OutFilesPath.c_str());//先检查是否完整
            }
            catch (std::exception&)
            {
                throw JGG::OpenFileException();
            }

            //引入.out文件解析对象
            BPA::BPAFilesIO::OutParse *inst = new BPA::BPAFilesIO::OutParse();

            //若完整
            if (Completeness1 == 1)
            {
                int InstabilityFlag = 0;
                try
                {
                    InstabilityFlag = InstabilityJudge(inst, OutFilesPath.c_str());//判稳
                }
                catch (std::exception&)
                {
                    throw JGG::OpenFileException();
                }

                //若失稳
                if (InstabilityFlag == 1)
                {
                    string OutFilesPath_str = OutFilesPath;
                    // 					strcpy_s(NewSWIFileNamePath.c_str(),OutFilesPath_str.substr(0,strlen(OutFilesPath.c_str())-4).c_str());
                    // 					strcat_s(NewSWIFileNamePath.c_str(),SWIFileType);
                    NewSWIFileNamePath = OutFilesPath_str.substr(0, strlen(OutFilesPath.c_str()) - 4);
                    NewSWIFileNamePath = NewSWIFileNamePath.append(SWIFileType);
                    //解析SWI文件
                    try
                    {
                        SwiFileDataRead(inst, NewSWIFileNamePath.c_str());
                    }
                    catch (std::exception&)
                    {
                        throw JGG::OpenFileException();
                    }

                    //判断设备信息是否存在
                    int EquInfoFlag = 0;
                    try
                    {
                        EquInfoFlag = EquipmentInfoCheck(inst, OutFilesPath.c_str());
                    }
                    catch (std::exception&)
                    {
                        throw JGG::OpenFileException();
                    }


                    //若设备信息不存在
                    if (EquInfoFlag == 0)
                    {
                        if (BseExist == 1)//已指定.bse位置
                        {
                            //重新生成OUT
                            char* NewRewriteOutFileNameTemp = nullptr;
                            try
                            {
                                NewRewriteOutFileNameTemp = BatchReWriteSwiFile(inst, NewSWIFileNamePath.c_str(), OutFilesPath.c_str(), BseName.c_str(), Completeness1);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::FileException();
                            }

                            char NewRewriteOutFileName[400] = "";
                            strcpy_s(NewRewriteOutFileName, NewRewriteOutFileNameTemp);

                            //解析OUT文件
                            try
                            {
                                inst->Parsing(NewRewriteOutFileName);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OpenFileException();
                                throw JGG::OutOfMemoryException();
                            }

                            //解析OUT数据分析
                            try
                            {
                                OutDataAnalysis(inst);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OutOfMemoryException();
                            }

                            //写入数据库
                            try
                            {
                                BatchOutFilesWriteToDataBase(inst, DB_NAME, NewRewriteOutFileName, CaseID, i);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OutOfMemoryException();
                            }
                        }
                        else//未指定.bse位置
                        {
                            cout << "警告!" << endl;
                            cout << "未指定.bse位置！\n" << endl;
                            LogOut << "警告!" << endl;
                            LogOut << "未指定.bse位置！\n" << endl;
                        }
                    }
                    //若设备信息存在
                    else
                    {
                        //解析OUT文件
                        try
                        {
                            inst->Parsing(OutFilesPath.c_str());
                        }
                        catch (std::exception&)
                        {
                            throw JGG::OpenFileException();
                            throw JGG::OutOfMemoryException();
                        }
                        //解析OUT数据分析
                        try
                        {
                            OutDataAnalysis(inst);
                        }
                        catch (std::exception&)
                        {
                            throw JGG::OutOfMemoryException();
                        }

                        //写入数据库
                        try
                        {
                            BatchOutFilesWriteToDataBase(inst, DB_NAME, OutFilesPath.c_str(), CaseID, i);
                        }
                        catch (std::exception&)
                        {
                            throw JGG::OutOfMemoryException();
                        }
                    }
                }
                else//若稳定
                {
                    try
                    {
                        string StableState = "稳定";
                        bufSQL.format("insert into OutStateList(CaseID,FileID,State) values (%d,%d,'%s') ;",
                            CaseID, i, StableState.c_str());
                        db.execDML(bufSQL);
                    }
                    catch (std::exception&)
                    {
                        throw JGG::OutOfMemoryException();
                    }

                    try
                    {
                        ofstream   LogOut("LogInfo_OutFilesAnalysis.txt ", ios::app);
                        cout << "该OUT文件是稳定的。\n" << endl;
                        LogOut << "该OUT文件是稳定的。\n" << endl;
                        LogOut.close();
                    }
                    catch (std::exception&)
                    {
                        throw JGG::FileException();
                    }
                }
            }
            //若不完整
            else
            {
                try
                {
                    ofstream LogOut("LogInfo_OutFilesAnalysis.txt ", ios::app);
                    cout << OutFilesPath << "该OUT文件意外中断。" << endl;
                    LogOut << OutFilesPath << "该OUT文件意外中断。" << endl;
                    LogOut.close();
                }
                catch (std::exception&)
                {
                    throw JGG::FileException();
                }


                if (BseExist == 1)//已指定.bse位置
                {
                    /////////重新生成OUT/////////
                    string OutFilesPath_str = OutFilesPath;
                    //strcpy_s(NewSWIFileNamePath.c_str(),OutFilesPath_str.substr(0,strlen(OutFilesPath.c_str())-4).c_str());
                    //strcat_s(NewSWIFileNamePath.c_str(),SWIFileType);
                    NewSWIFileNamePath = OutFilesPath_str.substr(0, strlen(OutFilesPath.c_str()) - 4);
                    NewSWIFileNamePath = NewSWIFileNamePath.append(SWIFileType);
                    //解析SWI文件
                    try
                    {
                        SwiFileDataRead(inst, NewSWIFileNamePath.c_str());
                    }
                    catch (std::exception&)
                    {
                        throw JGG::OpenFileException();
                    }

                    int Completeness = 1;//先不加周波
                    char* NewRewriteOutFileNameTemp = nullptr;
                    try
                    {
                        NewRewriteOutFileNameTemp = BatchReWriteSwiFile(inst, NewSWIFileNamePath.c_str(), OutFilesPath.c_str(), BseName.c_str(), Completeness);
                    }
                    catch (std::exception&)
                    {
                        throw JGG::FileException();
                    }
                    char NewRewriteOutFileName[400] = "";
                    strcpy_s(NewRewriteOutFileName, NewRewriteOutFileNameTemp);



                    ////////再检查一遍////////

                    int Completeness2 = 0;
                    try
                    {
                        Completeness2 = CompletenessCheck(NewRewriteOutFileName);//先检查是否完整
                    }
                    catch (std::exception&)
                    {
                        throw JGG::OpenFileException();
                    }
                    //若不完整
                    if (Completeness2 == 0)
                    {
                        try
                        {
                            ofstream   LogOut("LogInfo_OutFilesAnalysis.txt ", ios::app);
                            cout << "重写后依旧中断" << endl;
                            LogOut << "重写后依旧中断\n" << endl;
                            LogOut.close();
                        }

                        catch (std::exception&)
                        {
                            throw JGG::FileException();
                        }
                        try
                        {
                            string ProblemInfo = "该OUT文件意外中断！";
                            bufSQL.format("insert into OutProblemList(CaseID,FileID,ProblemInfo) values (%d,%d,'%s');",
                                CaseID, i, ProblemInfo.c_str());
                            db.execDML(bufSQL);
                        }
                        catch (std::exception&)
                        {
                            throw JGG::OutOfMemoryException();
                        }
                    }
                    //若完整
                    else
                    {
                        /////////对新生成的OUT判稳/////////
                        int InstabilityFlag1 = 0;
                        try
                        {
                            InstabilityFlag1 = InstabilityJudge(inst, OutFilesPath.c_str());//判稳
                        }
                        catch (std::exception&)
                        {
                            throw JGG::OpenFileException();
                        }

                        if (InstabilityFlag1 == 1)
                        {
                            //解析OUT文件
                            try
                            {
                                inst->Parsing(NewRewriteOutFileName);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OpenFileException();
                                throw JGG::OutOfMemoryException();
                            }

                            //解析OUT数据分析
                            try
                            {
                                OutDataAnalysis(inst);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OutOfMemoryException();
                            }

                            //写入数据库
                            try
                            {
                                BatchOutFilesWriteToDataBase(inst, DB_NAME, NewRewriteOutFileName, CaseID, i);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OutOfMemoryException();
                            }

                        }
                        else
                        {
                            try
                            {
                                string StableState = "稳定";
                                bufSQL.format("insert into OutStateList(CaseID,FileID,State) values (%d,%d,'%s');",
                                    CaseID, i, StableState.c_str());
                                db.execDML(bufSQL);
                            }
                            catch (std::exception&)
                            {
                                throw JGG::OutOfMemoryException();
                            }

                            try
                            {
                                cout << "该OUT文件是稳定的。\n" << endl;
                                LogOut << "该OUT文件是稳定的。\n" << endl;
                                LogOut.close();
                            }
                            catch (std::exception&)
                            {
                                throw JGG::FileException();
                            }
                        }
                    }
                }
                else//未指定.bse位置
                {
                    cout << "警告!" << endl;
                    cout << "未指定.bse位置！\n" << endl;
                    LogOut << "警告!" << endl;
                    LogOut << "未指定.bse位置！\n" << endl;
                }
            }
        }
    }
    db.close();
}
